package com.geeyuu.android.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.widget.ImageView;

import com.geeyuu.android.GeeConstants;
import com.geeyuu.android.R;
import com.geeyuu.android.utils.HttpUtil.HttpDownloadListener;

public class ImageLoder {

    public static final int IMG_SIZE_75 = 75;
    public static final int IMG_SIZE_150 = 150;
    public static final int IMG_SIZE_300 = 300;
    public static final int IMG_SIZE_320 = 320;
    public static final int IMG_SIZE_640 = 640;

    private int smallSize;
    private int bigSize;

    private static final String TAG = "ImageLoder";
    private static final char FLAG = '\n';
    private Context mContext;
    private MyHandler mHander;
    // private ExecutorService pool;

    private static ConcurrentHashMap<String, SoftReference<Bitmap>> bitmapsCache;
    private CopyOnWriteArrayList<String> urls = new CopyOnWriteArrayList<String>();
    private CopyOnWriteArrayList<String> downloadingUrls = new CopyOnWriteArrayList<String>();
    private ConcurrentHashMap<String, ImageView> imageCache = new ConcurrentHashMap<String, ImageView>();
    
    public int screenWidth;

    public ImageLoder(Context context) {
        if(bitmapsCache == null){
            bitmapsCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>();
        }
        this.mContext = context;
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager wm = (WindowManager) this.mContext.getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(metrics);
        screenWidth = metrics.widthPixels;
        if (screenWidth < 480) {
            smallSize = IMG_SIZE_75;
            bigSize = IMG_SIZE_320;
        } else if (screenWidth <= 640) {
            smallSize = IMG_SIZE_150;
            bigSize = IMG_SIZE_640;
        } else {
            smallSize = IMG_SIZE_300;
            bigSize = IMG_SIZE_640;
        }
        mHander = new MyHandler(context.getMainLooper(), this);
        LogUtil.i(TAG, "屏幕宽: " + screenWidth);
    }

    private static class MyHandler extends Handler {
        private final WeakReference<ImageLoder> mImageLoder;

        public MyHandler(Looper looper, ImageLoder context) {
            super(looper);
            mImageLoder = new WeakReference<ImageLoder>(context);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Bitmap bitmap = msg.getData().getParcelable("bitmap");
            String url = (String) msg.obj;
            ImageView imageView = mImageLoder.get().imageCache.remove(url);
            if (null != bitmap && null != imageView) {
                imageView.setImageBitmap(bitmap);
            } else {
                LogUtil.w(TAG, "bitmap or imageView is null, bitmap: " + bitmap + " imageView: " + imageView);
            }
            mImageLoder.get().downloadingUrls.remove(url);
        }
    }

    private int setFromCache(String url, ImageView imageView){
        SoftReference<Bitmap> softBitmap = bitmapsCache.get(url); // 在缓存里找
        if (null != softBitmap) {
            Bitmap bufferBitmap = softBitmap.get();
            if (null != bufferBitmap) {
                imageView.setImageBitmap(bufferBitmap);
                return 0;
            }
        }
        return -1;
    }
    
    private int setFromFile(String url, ImageView imageView, boolean isSmall, String photoId){
        File file = null; // 文件夹中找
        if (isSmall) {
            file = new File(GeeConstants.PATH_SMALL_IMAGE_FOLDER, photoId);
        } else {
            file = new File(GeeConstants.PATH_LARGE_IMAGE_FOLDER, photoId);
        }
        if (file.exists() && file.length() > 0) {
            Bitmap fileBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
            if (null != fileBitmap) {
                bitmapsCache.put(url, new SoftReference<Bitmap>(fileBitmap)); // 存进缓存
                imageView.setImageBitmap(fileBitmap);
                return 0;
            }
        }
        return -1;
    }
    
    public void add(final String photoId, ImageView imageView, final boolean isSmall) {

        imageView.setImageResource(R.drawable.default_avatar);

        if (CommonUtil.isEmpty(photoId) || photoId.length() < 3) {
            LogUtil.d(TAG, "参数photoId不正确");
            return;
        }
        
        String url = "";
        final String smallUrl = GeeConstants.IMG_DOWNLOAD_HTTP_URL + "?" + "fid=" + photoId + "&level=" + smallSize;
        final String bigUrl = GeeConstants.IMG_DOWNLOAD_HTTP_URL + "?" + "fid=" + photoId + "&level=" + bigSize;
        
        if (isSmall) {
            url = smallUrl;
        } else {
            url = bigUrl;
        }
        
        if(setFromCache(url, imageView) == 0){
            return;
        }else{
            if(!isSmall){
                setFromCache(smallUrl, imageView);
            }
        }

        if(setFromFile(url, imageView, isSmall, photoId) == 0){
            return;
        }else{
            if(!isSmall){
                setFromFile(smallUrl, imageView, true, photoId);
            }
        }

        if (imageCache.containsKey(url)) {
            imageCache.put(url, imageView);
        } else {
            if (imageCache.size() >= 28) {
                imageCache.remove(urls.get(0));
            }
            imageCache.put(url, imageView);
        }

        if (urls.contains(url) || downloadingUrls.contains(url)) {
            return;
        } else {
            if (urls.size() >= 28) {
                urls.remove(0);
            }
            urls.add(url);
        }

        fetchImage();
        
    }

    private static final int THREAD_COUNT = 4;
    private Thread[] threads = new Thread[THREAD_COUNT];
    
    private void fetchImage() {
        synchronized (threads) {
            for (int i = 0; i < THREAD_COUNT; i++) {
                if(threads[i] == null){
                    threads[i] = new Thread(new FetchImgThread(i));
                    threads[i].start();
                }
                if(urls.size() <= i+1 ){
                    break;
                }
            }
        }
    }

    private class FetchImgThread implements Runnable {
        
        public final int threadIndex;
        
        public FetchImgThread(int index){
            threadIndex = index;
        }

        @Override
        public void run() {
            String thisUrl = null;
            while (!urls.isEmpty()) {
                
                
                try {
                    thisUrl = urls.remove(urls.size() - 1);
                } catch (Exception e1) {
                    continue;
                }
                
                downloadingUrls.add(thisUrl);
                
                HttpUtil.getForBytes(thisUrl, 3, 3000, new HttpDownloadListener() { // 下载图片
                            @Override
                            public void onDownloadFinish(byte[] imgBytes, String url) {
                                int index = 0;
                                for (int i = 0; i < imgBytes.length; i++) {
                                    if (imgBytes[i] == FLAG) {
                                        index = i + 1;
                                        LogUtil.i(TAG, "========= 找到标记了, index:" + index);
                                        break;
                                    }
                                }
                                final int argIndex0 = url.indexOf("fid=");
                                final int argIndex1 = url.indexOf("&level=");
                                String photoId = url.substring(argIndex0 + 4, argIndex1);
                                String levelStr = url.substring(argIndex1 + 7);
                                boolean isSmall = true;
                                try {
                                    int level = Integer.valueOf(levelStr);
                                    if (level <= IMG_SIZE_300) {
                                        isSmall = true;
                                    } else {
                                        isSmall = false;
                                    }
                                } catch (Exception e) {
                                    LogUtil.e(TAG, "严重错误，url格式不对，截取不了url中的level");
                                }
                                try {
                                    final Bitmap imgBitmap = BitmapFactory.decodeByteArray(imgBytes, index,
                                            imgBytes.length - index);
                                    if (null != imgBitmap) {

                                        // 存进缓存
                                        bitmapsCache.put(url, new SoftReference<Bitmap>(imgBitmap));

                                        // 存进文件
                                        File file = null;
                                        if (isSmall) {
                                            file = new File(GeeConstants.PATH_SMALL_IMAGE_FOLDER, photoId);
                                        } else {
                                            file = new File(GeeConstants.PATH_LARGE_IMAGE_FOLDER, photoId);
                                        }
                                        file.delete();
                                        FileOutputStream fos = new FileOutputStream(file);
                                        imgBitmap.compress(CompressFormat.JPEG, 60, fos);
                                        fos.close();

                                        // 更新imageview
                                        if(!isDestory){
                                            Message msg = mHander.obtainMessage(0, url);
                                            Bundle bundle = new Bundle();
                                            bundle.putParcelable("bitmap", imgBitmap);
                                            msg.setData(bundle);
                                            msg.sendToTarget();
                                        }

                                    } else {
                                        LogUtil.e(TAG, "下载的bytes读取为bitmap is null");
                                        imageCache.remove(url);
                                        downloadingUrls.remove(url);
                                    }
                                } catch (Exception e) {
                                    LogUtil.e(TAG, "下载的bytes读取为bitmap有异常", e);
                                    imageCache.remove(url);
                                    downloadingUrls.remove(url);
                                }
                            }

                            @Override
                            public void onDownloadFail(String url) {
                                LogUtil.e(TAG, "下载bytes失败");
                                imageCache.remove(url);
                                downloadingUrls.remove(url);
                            }
                        });
                
                
            }
            
            synchronized (threads) {
                threads[threadIndex] = null;
            }
            
            
        }
    }
    
    private boolean isDestory = false;

    public void destory() {
        isDestory = true;
        urls.clear();
        downloadingUrls.clear();
        imageCache.clear();
    }

}
